2.3. Combinatorics ===================== Basic combinatorics can be performed fairly simple with the objects **RhoCandList** and **RhoCandidate**. After using the ``PndAnalysis::FillList`` method, you start your analysis code with a couple of filled lists. (Example code in macro **tut_ana_comb.C/tut_ana.C** in the tutorial directory.) In our example, we start with muons and anti-muons, selected with *loose* criterion using the combination =PidAlgoMdtHardCuts;PidAlgoMvd;PidAlgoStt;PidAlgoDrc= (not necessarily the best for this purpose, just exemplarily):: RhoCandList muplus, muminus, jpsi; ... // ... in event loop ... theAnalysis->FillList(muplus, "MuonLoosePlus","PidAlgoMdtHardCuts;PidAlgoMvd;PidAlgoStt;PidAlgoDrc"); theAnalysis->FillList(muminus, "MuonLooseMinus","PidAlgoMdtHardCuts;PidAlgoMvd;PidAlgoStt;PidAlgoDrc"); In order to fill the list named ``jpsi`` with *J/psi -> mu+ mu-* candidates based on the ``RhoCandidate::Combine`` method, we could use a classical nested loop like this:: // clean jpsi list and fill it with mu+ mu- combinations jpsi.Cleanup(); for (j=0;jCombine(muminus[k]); // ... some computation or checks ... jpsi.Append(combCand); } The advantage of coding like this is, that certain operations can be done in between, before actually appending the candidate to the list. When you really just want to do simple combinatorics, the complete routine from above can be short-cutted by using ``RhoCandList::Combine`` to:: jpsi.Combine(muplus,muminus); In order to reduce combinatorics, a cut on the invariant mass can be applied very easily by defining a mass selector with:: center of selection window v RhoMassParticleSelector *jpsiMassSel=new RhoMassParticleSelector("jpsi",3.096,1.0); ^ full width of window someplace outside of the event loop and applying it to a list with:: jpsi.Select(jpsiMassSel); For the complete combinatorics for our decay tree *psi(2S) -> J/psi pi+ pi- -> mu+ mu- pi+ pi-* only the following lines of code are necessary:: ... // ... in event loop ... theAnalysis->FillList(muplus, "MuonAllPlus"); theAnalysis->FillList(muminus, "MuonAllMinus"); theAnalysis->FillList(piplus, "PionAllPlus"); theAnalysis->FillList(piminus, "PionAllMinus"); jpsi.Combine(muplus, muminus); jpsi.Select(jpsiMassSel); psi.Combine(jpsi,piplus,piminus); (When you are wondering, why no PID algorithm is specified: Since we want to select all particles and just set the mass hypothesis, we don't care in this case.) This kind of doing combinatorics with ``RhoCandList::Combine`` avoids double counting (which easily happens when doing combinatorics with indistinguishable particles, e.g. forming gamma gamma combinations) and overlaps (which means, that a certain reconstructed particle appears more than once in a composite candidate with e.g. different mass hypotheses). The results for the combinatorics for the *J/psi* and the *psi(2S)* with no PID requirement look like this: .. image:: ./Images/hjpsim_all.png :width: 350 :alt: J/psi mass with no PID .. image:: ./Images/hpsim_all.png :width: 350 :alt: psi(2S) with no PID The same spectra with tight PID applied look like this: .. image:: ./Images/hjpsim_tpid.png :width: 350 :alt: J/psi with tight PID .. image:: ./Images/hpsim_tpid.png :width: 350 :alt: psi(2S) with tight PID You can see in particular in the left plot, that the wrong combinations of *J/psi* based on pion tracks at low invariant masses are significantly suppressed.